package com.yuan.fullstackback.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.yuan.fullstackback.model.userRequest.LoginBody;
import com.yuan.fullstackback.model.userRequest.PasswordRequest;
import com.yuan.fullstackback.model.userRequest.UrlRequest;
import com.yuan.fullstackback.model.userRequest.UserEntityBody;
import com.yuan.fullstackback.pojo.SysUser;
import com.yuan.fullstackback.service.impl.SysUserServiceImpl;
import com.yuan.fullstackback.utils.AjaxResult;
import com.yuan.fullstackback.utils.JwtUtil;
import com.yuan.fullstackback.utils.Md5Util;
import com.yuan.fullstackback.utils.ThreadLocalUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

import static com.yuan.fullstackback.utils.AjaxResult.error;

/**
 * 用户信息
 */
@RestController
@RequestMapping("/system/user")
public class SysUserController {

    @Autowired
    private SysUserServiceImpl sysUserService;

    /**
     * 注册验证：传输一个用户对象
     *
     * @param registerUser 注册实体类
     * @return 通用返回对象
     */
    @PostMapping("/register")
    public AjaxResult register(@Validated @RequestBody UserEntityBody registerUser) {
        //判断用户名的唯一性[查数据库]
        SysUser userByName = sysUserService.selectUserByUserName(registerUser.getUserName());
        if (ObjectUtil.isNotEmpty(userByName)) return error("用户名已被占用");
        //注册
        if (sysUserService.registerUser(registerUser)) {
            return AjaxResult.success("注册成功");
        } else
            return error("注册失败，请检查网络");
    }

    /**
     * 登录方法
     *
     * @param loginBody 登录实体类
     * @return 通用返回对象
     */
    @PostMapping("/login")
    public AjaxResult login(@Validated @RequestBody LoginBody loginBody) {
        // 根据用户名查询User
        SysUser loginUser = sysUserService.selectUserByUserName(loginBody.getUserName());
        // 判断是否查询到
        if (ObjectUtil.isEmpty(loginUser)) return error("用户不存在");
        // 判断密码是否正确
        if (!StrUtil.equals(loginUser.getPassword(), Md5Util.getMD5String(loginBody.getPassword()))) {
            return error("密码错误");
        }
        loginUser.setPassword("");//设空密码
        Map<String, Object> claims = BeanUtil.beanToMap(loginUser);
        claims.put("id", loginUser.getUserId());
        return AjaxResult.success("登陆成功", JwtUtil.genToken(claims));
    }

    /**
     * 用户详细信息
     */
    @GetMapping("/getInfo")
    public AjaxResult getInfo() {
        Map<String, Object> claims = ThreadLocalUtil.get();
        SysUser user = sysUserService.selectUserByUserName((String) claims.get("userName"));
        return AjaxResult.success(user);
    }

    /**
     * 更新用户
     *
     * @param user 当前登录的用户
     * @return 修改状态
     */
    @PutMapping("/update")
    public AjaxResult updateProfile(@RequestBody UserEntityBody user) {
        //只能修改昵称手机号（用户名默认为邮箱，注册成功就不可以修改了,密码为单独修改）
        SysUser currentUser = new SysUser();
        //防止拦截传参修改用户名
        Map<String, Object> claims = ThreadLocalUtil.get();
        if (!StrUtil.equals((String) claims.get("userName"), user.getUserName())) {
            return AjaxResult.error("用户名不可修改");
        }
        BeanUtil.copyProperties(user, currentUser);
        if (sysUserService.updateUserInfo(currentUser) != 1) return AjaxResult.error("修改失败，重新填写");
        // 更新缓存用户信息
        // tokenService.setLoginUser(loginUser);
        return AjaxResult.success("更新成功");
    }

    /**
     * 头像上传
     */
    @PatchMapping("/avatar")
    public AjaxResult avatar(@Validated @RequestBody UrlRequest urlRequest) {
        //不是一个链接：直接返回
        try {
            HttpUtil.get(urlRequest.getAvatarUrl(), CharsetUtil.CHARSET_UTF_8);
            if (sysUserService.updateUserAvatar(urlRequest.getAvatarUrl()) != 1)
                return AjaxResult.error("修改失败,重新上传");
        } catch (Exception e) {
            return AjaxResult.error("URL不合法");
        }
        return AjaxResult.success("更新成功");
    }

    /**
     * 重置密码
     */
    @PutMapping("/updatePwd")
    public AjaxResult updatePwd(@Validated @RequestBody PasswordRequest pawRequest) {
        Map<String, Object> claims = ThreadLocalUtil.get();
        String password = sysUserService.selectUserByUserName((String) claims.get("userName")).getPassword();
        //前端需要处理一次，后端做处理是为了业务逻辑的完整性
        if (!StrUtil.equals(Md5Util.getMD5String(pawRequest.getOldPassword()), password))
            return AjaxResult.error("旧密码输入错误");
        if (StrUtil.equals(pawRequest.getOldPassword(), pawRequest.getNewPassword()))
            return AjaxResult.error("旧密码与旧密码相同");
        if (sysUserService.resetUserPwd(Md5Util.getMD5String(pawRequest.getNewPassword())) != 0) {
            return AjaxResult.error("修改密码异常，请联系管理员");
        }
        return AjaxResult.success("更新成功");
    }
}